package net.butfly.bus.client.connection;

import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;

import net.butfly.albacore.exception.SystemException;
import net.butfly.bus.Constants;
import net.butfly.bus.EntryPoint;
import net.butfly.bus.Request;
import net.butfly.bus.Response;
import net.butfly.bus.impl.Connection;
import net.butfly.bus.util.EnumFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.caucho.hessian.client.HessianConnectionException;
import com.caucho.hessian.client.HessianProxyFactory;
import com.caucho.hessian.client.HessianRuntimeException;
import com.caucho.hessian.io.AbstractSerializerFactory;

public class HessianConnection implements Connection {
	private static Logger logger = LoggerFactory.getLogger(HessianConnection.class);

	private String path;

	private long connectionTimeout = 5000;

	// private List<Map<String, String>> translator;

	public HessianConnection(String path, long timeout, List<Map<String, String>> translator) {
		this.path = path;
		this.connectionTimeout = timeout > 0 ? timeout : connectionTimeout;
		// translator = translator;
	}

	public Response send(Request request) {
		try {
			HessianProxyFactory factory = new HessianProxyFactory();

			AbstractSerializerFactory af = null;
			try {
				af = (AbstractSerializerFactory) Thread.currentThread().getContextClassLoader()
						.loadClass(Constants.Configuration.ENUM_FACTORY_CLASSNAME).newInstance();
			} catch (Exception ex) {
				af = new EnumFactory();
			}
			factory.getSerializerFactory().addFactory(af);
			factory.setConnectTimeout(connectionTimeout);

			EntryPoint proxy = (EntryPoint) factory.create(EntryPoint.class, path);
			logger.info("Attemp hessian connection: " + path + ".");
			return (Response) proxy.invoke(request);
		} catch (MalformedURLException ex) {
			throw new SystemException(Constants.SystemError.HESSIAN_CONNECTION, "Hessian url [" + path + "] invalid.", ex);
		} catch (HessianConnectionException ex) {// 连接异常
			throw new SystemException(Constants.SystemError.HESSIAN_CONNECTION, "Hessian connection [" + path + "] invalid.",
					ex);
		} catch (HessianRuntimeException ex) {
			throw new SystemException(Constants.SystemError.HESSIAN_CONNECTION, "Hessian service [" + path + "] invalid.",
					ex.getCause());
		}
	}
}
